/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 
#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "drv_api.h"
#include "diag.h"
#include "wbio.h"
#include "NUC900_GE.h"
#include "NUC900_reg.h"
#else
#include <stdio.h>
#include "NUC900_GE.h"
#include "wbio.h"
#ifdef _NUC900_
#include "NUC900_reg.h"
#else
#include "reg702.h"
#endif
#endif

typedef struct
{ 
  UINT32 Index;
  UINT32 PowerOn;
  UINT32 BitMask;
} REG_INFO;

static UINT32 BIT32[32] = 
{
 0x00000001, 0x00000002, 0x00000004, 0x00000008,
 0x00000010, 0x00000020, 0x00000040, 0x00000080,
 0x00000100, 0x00000200, 0x00000400, 0x00000800,
 0x00001000, 0x00002000, 0x00004000, 0x00008000,
 0x00010000, 0x00020000, 0x00040000, 0x00080000,
 0x00100000, 0x00200000, 0x00400000, 0x00800000,
 0x01000000, 0x02000000, 0x04000000, 0x08000000,
 0x10000000, 0x20000000, 0x40000000, 0x80000000
};
			  
static REG_INFO RegInfoTbl[] =
{
  {REG_2D_GETG,				0x00000000, 0x00000000},
#ifdef _NUC900_  
  {REG_2D_GEXYSORG, 	0x00000000, 0x0fffffff}, 
  {REG_2D_GEXYSORG,  	0x00000000, 0x0fffffff},   
  {REG_2D_TileXY_VHSF,  				0x00000000, 0x0000ffff}, 
  {REG_2D_TileXY_VHSF,  				0x00000000, 0xffffffff}, 
  {REG_2D_GERRXY,  				0x00000000, 0x07ff07ff}, 
#else  
  {REG_2D_GEXYSORG, 	0x00000000, 0xffffffff}, 
  {REG_2D_GEXYSORG,  	0x00000000, 0xffffffff}, 
  {REG_2D_TileXY_VHSF,  			0x00000000, 0x00ffffff}, 
  {REG_2D_GERRXY,  			0x00000000, 0xffffffff}, 
#endif  
//  {REG_2D_GEINTS,  				0x0708e200, 0x00000000}, 
#ifdef _NUC900_ 
  {REG_2D_GEPLS,  		0x00000000, 0x0fffffff}, 
#else
  {REG_2D_GEPLS,  		0x00000000, 0xffffffff}, 
#endif  
  {REG_2D_GEBER,	0x00000000, 0xffffffff}, 
#ifdef _NUC900_
  {REG_2D_GEBIR,  		0x00000000, 0x3fff07ff}, 
#else  
  {REG_2D_GEBIR,  		0x00000000, 0xffffffff}, 
#endif  
  {REG_2D_GEC,  			0x00000000, 0xffffffff}, 
  {REG_2D_GEBC,  			0x00000000, 0x00ffffff}, 
  {REG_2D_GEFC,  			0x00000000, 0x00ffffff}, 
  {REG_2D_GETC,  	0x00000000, 0x00ffffff}, 
  {REG_2D_GETCM,  	0x00000000, 0x00ffffff},
#ifdef _NUC900_   
  {REG_2D_GEXYDORG,  	0x00000000, 0x0fffffff}, 
  {REG_2D_GEXYDORG,  	0x00000000, 0x0fffffff}, 
  {REG_2D_GESDP,  				0x00000000, 0x01ff01ff}, 
  {REG_2D_GESDP,  		0x00000000, 0x01ff01ff},   
  {REG_2D_GESSXYL,  		0x00000000, 0x07ff07ff},   
  {REG_2D_GEDSXYL,  	0x00000000, 0x07ff07ff},   
  {REG_2D_GEDIXYL,  			0x00000000, 0x07ff07ff}, 
  //{REG_GE_FILTER_DIMENSION,  	0x00000000, 0xffffffff}, 
  {REG_2D_GECBTL,  			0x00000000, 0x07ff07ff}, 
  {REG_2D_GECBBR,  			0x00000000, 0x07ff07ff},       
#else
  {REG_2D_GEXYDORG,  	0x00000000, 0xffffffff}, 
  {REG_2D_GEXYDORG,  	0x00000000, 0xffffffff},   
  {REG_2D_GESDP,  				0x00000000, 0xffffffff}, 
  {REG_2D_GESDP,  		0x00000000, 0xffffffff}, 
  {REG_2D_GESSXYL,  		0x00000000, 0xffffffff},   
  {REG_2D_GEDSXYL,  	0x00000000, 0xffffffff},   
  {REG_2D_GEDIXYL,  			0x00000000, 0xffffffff}, 
  //{REG_GE_FILTER_DIMENSION,  	0x00000000, 0xffffffff},   
  {REG_2D_GECBTL,  			0x00000000, 0xffffffff},   
  {REG_2D_GECBBR,  			0x00000000, 0xffffffff},   
#endif  
  {REG_2D_GEPTNA,  				0x00000000, 0xffffffff}, 
  {REG_2D_GEPTNB,  				0x00000000, 0xffffffff}, 
  {REG_2D_GEWPM,  			0x00000000, 0x00ffffff}, 
  {REG_2D_GEMC,  				0x00000800, 0xffff003f}, 
#if 0  
  {REG_2D_GEHBDW0,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT1,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT2,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT3,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT4,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT5,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT6,  			0x00000000, 0xffffffff}, 
  {REG_GE_DATA_PORT7,  			0x00000000, 0xffffffff}, 
#endif  
  {0x00000000, 					0x00000000, 0x00000000}
};


///////////////////////////////////////////////////////////////////////////////
//
// Function: test_reg_GE()
//
// Description:
//   This function is used to test the graphics engine registers.
//
///////////////////////////////////////////////////////////////////////////////
int test_reg_GE()
{
  UINT32 data32;
  UINT32 idx, mask, old_data, toggle_data;
  int reg_tbl_idx, test_bit;

  reg_tbl_idx = 0;
  while (RegInfoTbl[reg_tbl_idx].Index != 0x00000000)
  {
    #ifdef DEBUG
    printf("check register 0x%lx ... \n", RegInfoTbl[reg_tbl_idx].Index);
    #endif
    
    /* check power on default value */
    
    idx = RegInfoTbl[reg_tbl_idx].Index;
    if (idx != REG_2D_GETG)
    {
      data32 = inpw(idx);
    
      if (data32 != RegInfoTbl[reg_tbl_idx].PowerOn)
      {
        #ifdef DEBUG
        printf("power on default fail: 0x%lx\n", data32);
        #endif
        return 1;
      }   
    }

    /*
    ** idx = RegInfoTbl[reg_tbl_idx].Index;
    **/
    mask = RegInfoTbl[reg_tbl_idx].BitMask;

    old_data = inpw(idx); // keep old value
    for (test_bit=0; test_bit<32; test_bit++)
    {
      if ((mask&BIT32[test_bit])!=0x00000000) // check if R/W bit
         {
           toggle_data = old_data^BIT32[test_bit];
           outpw(idx, toggle_data); // toggle this bit
           data32 = inpw(idx);
           if (data32 != toggle_data) 
           {
             #ifdef DEBUG
             printf("bit %d fails\n", test_bit);
             #endif
             return 1;
           }  

           toggle_data = toggle_data^BIT32[test_bit];
           outpw(idx, toggle_data); // toggle again
           data32 = inpw(idx);
           if (data32 != old_data) 
           {
             #ifdef DEBUG
             printf("bit %d fails\n", test_bit);
             #endif
             return 1;
           }
         }
    }; // for
    
    //printf("OK\n");
    reg_tbl_idx++;
  }
  
  return 0; // success
} 
 
  